﻿#region Legal Disclaimer
// THIS SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN “AS IS” BASIS, WITHOUT 
// WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT 
// LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE IS FREE OF DEFECTS, 
// MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE 
// RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED SOFTWARE IS WITH 
// YOU. SHOULD ANY OF THIS SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT 
// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY 
// NECESSARY SERVICING, REPAIR OR CORRECTION. NO USE OF THIS SOFTWARE IS 
// AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
// 
// Microsoft Public License (Ms-PL) governs use of this software. If you use the software, 
// you accept this license. If you do not accept the license, do not use the software.
#endregion
using System;

namespace SimplyConfigured.Sources
{
    /// <summary>
    /// 
    /// </summary>
    public class DefaultConfigurationSource : IConfigurationSource
    {
        /// <summary>
        /// Gets the instance.
        /// </summary>
        /// <value></value>
        public IConfiguration Instance
        {
            get
            {
                Data = GetDefaultConfiguration(new SimpleConfiguration());
                return Data;
            }
        }

        /// <summary>
        /// Gets the configuration data for this specific data source.
        /// </summary>
        public IConfiguration Data { private set; get; }

        /// <summary>
        /// Gets the default configuration.
        /// </summary>
        /// <param name="config">The config.</param>
        /// <returns></returns>
        private static IConfiguration GetDefaultConfiguration(IConfiguration config)
        {
            if (config == null) throw new ArgumentNullException("config");

            var appSettingsConfig = System.Configuration.ConfigurationManager.AppSettings;

            foreach (var item in appSettingsConfig.AllKeys)
            {
                config[item] = appSettingsConfig[item];
            }

            var connectionConfig = System.Configuration.ConfigurationManager.ConnectionStrings;

            for (int i = 0; i < connectionConfig.Count; i++)
            {
                var item = connectionConfig[i];
                config[item.Name] = connectionConfig[i].ConnectionString;
            }

            return config;
        }

        #region Implementation of IConfigurationSourceObservable

        /// <summary>
        /// Occurs when configuration data changed.
        /// </summary>
        public event EventHandler<ConfigurationSourceChangedEventArgs> ConfigurationSourceChanged;

        /// <summary>
        /// Called when configuration data changed.
        /// </summary>
        /// <param name="e">The event arguments</param>
        public void OnConfigurationSourceChanged(ConfigurationSourceChangedEventArgs e)
        {
            if (ConfigurationSourceChanged != null)
            {
                ConfigurationSourceChanged(this, e);
            }
        }

        /// <summary>
        /// Attaches the specified observer.
        /// </summary>
        /// <param name="observer">The observer.</param>
        public void Attach(IConfigurationSourceChangeObserver observer)
        {
            ConfigurationSourceChanged += observer.UpdateConfigurationData;
        }

        /// <summary>
        /// Detaches the specified observer.
        /// </summary>
        /// <param name="observer">The observer.</param>
        public void Detach(IConfigurationSourceChangeObserver observer)
        {
            ConfigurationSourceChanged -= observer.UpdateConfigurationData;
        }

        #endregion
    }
}
